package com.httpClient.chapter1;

import com.sky.JULLog.MyJulLogger;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

/**
 * @author : wushikai
 *         date : 2024-06-17
 */
public class RetryHttpClient {


    private static Logger log = MyJulLogger.getLogger(RetryHttpClient.class);

    /**
     *
     * 请求重试处理;  mark 没有理解怎么用...
     * */
    private  static  HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {

        public boolean retryRequest(IOException exception,  int executionCount, HttpContext context) {

            log.warning("重连的次数是" +  executionCount);

            if (executionCount >= 5) { // 如果超过最大重试次数，那么就不要继续了
                return false;
            }
            if (exception instanceof NoHttpResponseException) { // 如果服务器丢掉了连接，那么就重试
                return true;
            }
            if (exception instanceof InterruptedIOException) {
                // Timeout
                return true;
            }
            if (exception instanceof UnknownHostException) {
                // Unknown host
                return true;
            }

            if (exception instanceof SSLHandshakeException) {  // 不要重试SSL握手异常
                return false;
            }
            HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
            boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
            // 如果请求被认为是幂等的，那么就重试
            return idempotent;
        }
    };



    public static void main(String[] args) throws Exception {
        doRequest();
    }


    private static void doRequest( ) throws IOException {


        DefaultHttpClient httpclient = new DefaultHttpClient();
        httpclient.setHttpRequestRetryHandler(myRetryHandler);

        HttpPost httpPost = new HttpPost("http://www.google.com");  //mark 谷歌是连不上的
        httpPost.abort();  //谷歌直接终止了
        HttpResponse response = httpclient.execute(httpPost);
        handleResponse(response);

    }


    /**
     * 使用最简单的 流式读取
     */
    private static void handleResponse(HttpResponse response) throws IOException {

        log.info("response 的实现类是==>" + response.getClass().getCanonicalName());
        log.info("协议版本:" + response.getProtocolVersion());
        log.info("服务器返回状态码:" + response.getStatusLine().getStatusCode());
        log.info("服务器返回状态码表述:" + response.getStatusLine().getReasonPhrase());
        log.info("服务器返回状态描述:" + response.getStatusLine().toString());

        if (response.getStatusLine().getStatusCode() !=  HttpStatus.SC_OK ){
            log.warning( "响应结果不是200, 直接返回");
            return ;
        }



        //使用 响应头 获取 cookie 键值对,  注意这是没有被解析过的
        Header h1 = response.getFirstHeader("Set-Cookie");
        log.info(h1.toString());
        Header h2 = response.getLastHeader("Set-Cookie");
        log.info(h2.toString());
        Header[] hs = response.getHeaders("Set-Cookie");
        log.info(hs.length + "");

        //使用 迭代器 获取 cookie 键值对 ,  httpClient 帮你解析好;
        HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator("Set-Cookie"));
        while (it.hasNext()) {
            HeaderElement elem = it.nextElement();
            log.info(elem.getName() + " = " + elem.getValue());
            NameValuePair[] params = elem.getParameters();
            for (NameValuePair param : params) {
                log.info(" " + param);
            }
        }


        HttpEntity entity = response.getEntity();   // 返回一个 HttpResponse 的 entity(实体) 这个  实体 = 响应头+响应内容

        if (entity != null) {
            InputStream inputStream = entity.getContent();   //实体对象 获取流 , 解析data 即可;
            byte[] buffer = new byte[2048];
            while (inputStream.read(buffer) != -1) {
                log.info("第一次读取的内容是:" + new String(buffer, StandardCharsets.UTF_8));
            }
            System.out.println();
            System.out.println("data  read  finished.......");
            inputStream.close();

        }



    }

}


